<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传与管理</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

    <!-- 配置Tailwind自定义颜色 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        danger: '#EF4444',
                        dark: '#1E293B',
                        light: '#F8FAFC'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .file-drop-active {
                @apply border-primary bg-blue-50;
            }
            .card-hover {
                @apply transition-all duration-300 hover:shadow-lg hover:-translate-y-1;
            }
            .tab-active {
                @apply bg-primary text-white;
            }
            .tab-container {
                @apply overflow-x-auto flex border-b border-gray-200 -mb-px;
            }
            .tab-button {
                @apply py-2 px-4 whitespace-nowrap rounded-t transition-colors;
            }
        }
    </style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8 max-w-6xl">
    <!-- 页面标题 -->
    <header class="mb-10 text-center">
        <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-dark mb-2">文件上传与管理系统</h1>
        <p class="text-gray-600">支持上传txt、json、word、pdf等格式文件，并提供Elasticsearch查询功能</p>
    </header>

    <main class="grid grid-cols-1 lg:grid-cols-3 gap-8">
        <!-- 上传区域 -->
        <section class="lg:col-span-1">
            <div class="bg-white rounded-xl shadow-md p-6 h-full">
                <h2 class="text-xl font-semibold mb-4 flex items-center">
                    <i class="fa fa-cloud-upload text-primary mr-2"></i>文件上传
                </h2>

                <!-- 上传区域 -->
                <div id="fileDropArea" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center transition-all cursor-pointer mb-6">
                    <i class="fa fa-file-text-o text-5xl text-gray-400 mb-4"></i>
                    <p class="text-gray-600 mb-2">拖放文件到此处，或</p>
                    <label class="inline-block bg-primary text-white py-2 px-6 rounded-md cursor-pointer hover:bg-primary/90 transition-colors">
                        <i class="fa fa-folder-open mr-1"></i>选择文件
                        <input type="file" id="fileInput" class="hidden" multiple accept=".txt,.json,.doc,.docx,.pdf">
                    </label>
                    <p class="text-xs text-gray-500 mt-4">支持格式: txt, json, word, pdf</p>
                </div>

                <!-- 上传按钮 -->
                <button id="uploadBtn" class="w-full bg-primary hover:bg-primary/90 text-white font-medium py-3 px-4 rounded-md transition-colors flex items-center justify-center">
                    <i class="fa fa-upload mr-2"></i>开始上传
                </button>

                <!-- 上传进度 -->
                <div id="progressContainer" class="hidden mt-4">
                    <div class="flex justify-between text-sm mb-1">
                        <span id="progressFileName">正在上传...</span>
                        <span id="progressPercent">0%</span>
                    </div>
                    <div class="w-full bg-gray-200 rounded-full h-2.5">
                        <div id="progressBar" class="bg-secondary h-2.5 rounded-full" style="width: 0%"></div>
                    </div>
                </div>

                <!-- 状态消息 -->
                <div id="statusMessage" class="mt-4 p-3 rounded-md hidden"></div>
            </div>
        </section>

        <!-- 右侧内容区域 -->
        <section class="lg:col-span-2">
            <div class="bg-white rounded-xl shadow-md p-6">
                <!-- 标签切换 -->
                <div class="tab-container mb-6">
                    <button id="localFilesTab" class="tab-button tab-active">
                        <i class="fa fa-hdd-o mr-1"></i>本地文件
                    </button>
                    <button id="elkSearchTab" class="tab-button text-gray-600 hover:bg-gray-100">
                        <i class="fa fa-search mr-1"></i>ELK搜索
                    </button>
                    <button id="allElkIdsTab" class="tab-button text-gray-600 hover:bg-gray-100">
                        <i class="fa fa-list mr-1"></i>所有ELK文档ID
                    </button>
                    <button id="singleDocTab" class="tab-button text-gray-600 hover:bg-gray-100">
                        <i class="fa fa-file-o mr-1"></i>单个文档查询
                    </button>
                </div>

                <!-- 1. 本地文件区域 -->
                <div id="localFilesSection">
                    <!-- 搜索和筛选 -->
                    <div class="mb-6">
                        <div class="relative">
                            <input type="text" id="searchLocalFiles" placeholder="搜索本地文件..."
                                   class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                            <i class="fa fa-search absolute left-3 top-3 text-gray-400"></i>
                        </div>
                    </div>

                    <!-- 批量操作 -->
                    <div class="mb-6 flex justify-between items-center">
                        <div>
                            <button id="selectAllBtn" class="text-primary hover:text-primary/80 text-sm mr-4">
                                <i class="fa fa-check-square-o mr-1"></i>全选
                            </button>
                            <button id="deselectAllBtn" class="text-gray-600 hover:text-gray-800 text-sm">
                                <i class="fa fa-square-o mr-1"></i>取消选择
                            </button>
                        </div>
                        <button id="batchDeleteBtn" class="bg-danger hover:bg-danger/90 text-white text-sm py-1 px-4 rounded-md transition-colors hidden">
                            <i class="fa fa-trash-o mr-1"></i>批量删除
                        </button>
                    </div>

                    <!-- 本地文件列表容器 -->
                    <div id="localFileList" class="divide-y divide-gray-100">
                        <div class="text-center py-12 text-gray-500">
                            <i class="fa fa-folder-open-o text-4xl mb-3"></i>
                            <p>暂无上传的文件</p>
                        </div>
                    </div>
                </div>

                <!-- 2. ELK搜索区域 -->
                <div id="elkSearchSection" class="hidden">
                    <!-- ELK查询表单 -->
                    <div class="mb-6 bg-gray-50 p-4 rounded-lg">
                        <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
                            <div class="md:col-span-2">
                                <input type="text" id="elkQueryText" placeholder="输入查询文本..."
                                       class="w-full pl-3 pr-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                            </div>
                            <div class="flex gap-2">
                                <input type="number" id="elkTopK" placeholder="返回数量" value="5" min="1" max="100"
                                       class="flex-1 pl-3 pr-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                                <button id="searchElkBtn" class="bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-md transition-colors">
                                    <i class="fa fa-search mr-1"></i>查询
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- ELK批量操作 -->
                    <div class="mb-6 flex justify-between items-center">
                        <div>
                            <button id="selectAllElkBtn" class="text-primary hover:text-primary/80 text-sm mr-4">
                                <i class="fa fa-check-square-o mr-1"></i>全选
                            </button>
                            <button id="deselectAllElkBtn" class="text-gray-600 hover:text-gray-800 text-sm">
                                <i class="fa fa-square-o mr-1"></i>取消选择
                            </button>
                        </div>
                        <div>
                            <button id="batchDeleteElkBtn" class="bg-danger hover:bg-danger/90 text-white text-sm py-1 px-4 rounded-md transition-colors hidden mr-2">
                                <i class="fa fa-trash-o mr-1"></i>批量删除
                            </button>
                            <button id="deleteAllElkBtn" class="bg-gray-600 hover:bg-gray-700 text-white text-sm py-1 px-4 rounded-md transition-colors">
                                <i class="fa fa-trash mr-1"></i>删除所有ELK文档
                            </button>
                        </div>
                    </div>

                    <!-- ELK查询结果容器 -->
                    <div id="elkFileList" class="divide-y divide-gray-100">
                        <div class="text-center py-12 text-gray-500">
                            <i class="fa fa-database text-4xl mb-3"></i>
                            <p>请输入查询条件搜索Elasticsearch中的文档</p>
                        </div>
                    </div>
                </div>

                <!-- 3. 所有ELK文档ID区域 -->
                <div id="allElkIdsSection" class="hidden">
                    <div class="mb-6">
                        <button id="fetchAllElkIdsBtn" class="bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-md transition-colors mb-4">
                            <i class="fa fa-refresh mr-1"></i>获取所有ELK文档ID
                        </button>
                        <div class="text-sm text-gray-500 mb-4">
                            <p><i class="fa fa-info-circle text-blue-500 mr-1"></i> 点击按钮加载Elasticsearch中所有文档的ID列表</p>
                        </div>
                    </div>

                    <!-- 操作按钮 -->
                    <div class="mb-6 flex justify-end">
                        <button id="deleteAllFromIdsBtn" class="bg-danger hover:bg-danger/90 text-white text-sm py-1 px-4 rounded-md transition-colors">
                            <i class="fa fa-trash mr-1"></i>删除所有文档
                        </button>
                    </div>

                    <!-- ID列表容器 -->
                    <div id="allElkIdsList" class="bg-gray-50 rounded-lg p-4 max-h-96 overflow-auto">
                        <div class="text-center py-12 text-gray-500">
                            <i class="fa fa-list-ol text-4xl mb-3"></i>
                            <p>请点击上方按钮获取所有文档ID</p>
                        </div>
                    </div>
                </div>

                <!-- 4. 单个文档查询区域 -->
                <div id="singleDocSection" class="hidden">
                    <div class="mb-6 bg-gray-50 p-4 rounded-lg">
                        <div class="flex gap-2">
                            <input type="text" id="singleDocId" placeholder="输入文档ID..."
                                   class="flex-1 pl-3 pr-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50">
                            <button id="fetchSingleDocBtn" class="bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-md transition-colors">
                                <i class="fa fa-search mr-1"></i>查询文档
                            </button>
                        </div>
                    </div>

                    <!-- 文档内容展示 -->
                    <div id="singleDocContent" class="border border-gray-200 rounded-lg overflow-hidden">
                        <div class="p-6 text-center text-gray-500">
                            <i class="fa fa-file-text-o text-4xl mb-3"></i>
                            <p>请输入文档ID查询详细内容</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <footer class="mt-12 text-center text-gray-500 text-sm">
        <p>文件上传与管理系统 &copy; 2023</p>
    </footer>
</div>

<script>
    // 配置基础API URL
    const API_BASE_URL = 'http://localhost:8080';

    // DOM元素 - 通用
    const statusMessage = document.getElementById('statusMessage');

    // DOM元素 - 上传相关
    const fileDropArea = document.getElementById('fileDropArea');
    const fileInput = document.getElementById('fileInput');
    const uploadBtn = document.getElementById('uploadBtn');
    const progressContainer = document.getElementById('progressContainer');
    const progressBar = document.getElementById('progressBar');
    const progressFileName = document.getElementById('progressFileName');
    const progressPercent = document.getElementById('progressPercent');

    // DOM元素 - 标签切换
    const localFilesTab = document.getElementById('localFilesTab');
    const elkSearchTab = document.getElementById('elkSearchTab');
    const allElkIdsTab = document.getElementById('allElkIdsTab');
    const singleDocTab = document.getElementById('singleDocTab');
    const localFilesSection = document.getElementById('localFilesSection');
    const elkSearchSection = document.getElementById('elkSearchSection');
    const allElkIdsSection = document.getElementById('allElkIdsSection');
    const singleDocSection = document.getElementById('singleDocSection');

    // DOM元素 - 本地文件
    const localFileList = document.getElementById('localFileList');
    const searchLocalFiles = document.getElementById('searchLocalFiles');
    const selectAllBtn = document.getElementById('selectAllBtn');
    const deselectAllBtn = document.getElementById('deselectAllBtn');
    const batchDeleteBtn = document.getElementById('batchDeleteBtn');

    // DOM元素 - ELK搜索
    const elkFileList = document.getElementById('elkFileList');
    const elkQueryText = document.getElementById('elkQueryText');
    const elkTopK = document.getElementById('elkTopK');
    const searchElkBtn = document.getElementById('searchElkBtn');
    const selectAllElkBtn = document.getElementById('selectAllElkBtn');
    const deselectAllElkBtn = document.getElementById('deselectAllElkBtn');
    const batchDeleteElkBtn = document.getElementById('batchDeleteElkBtn');
    const deleteAllElkBtn = document.getElementById('deleteAllElkBtn');

    // DOM元素 - 所有ELK文档ID
    const fetchAllElkIdsBtn = document.getElementById('fetchAllElkIdsBtn');
    const allElkIdsList = document.getElementById('allElkIdsList');
    const deleteAllFromIdsBtn = document.getElementById('deleteAllFromIdsBtn');

    // DOM元素 - 单个文档查询
    const singleDocId = document.getElementById('singleDocId');
    const fetchSingleDocBtn = document.getElementById('fetchSingleDocBtn');
    const singleDocContent = document.getElementById('singleDocContent');

    // 初始化标签切换
    function initTabs() {
        localFilesTab.addEventListener('click', () => switchTab('local'));
        elkSearchTab.addEventListener('click', () => switchTab('elk-search'));
        allElkIdsTab.addEventListener('click', () => switchTab('all-elk-ids'));
        singleDocTab.addEventListener('click', () => switchTab('single-doc'));
    }

    function switchTab(tabName) {
        // 重置所有标签状态
        [localFilesTab, elkSearchTab, allElkIdsTab, singleDocTab].forEach(tab => {
            tab.classList.remove('tab-active');
            tab.classList.add('text-gray-600', 'hover:bg-gray-100');
        });
        [localFilesSection, elkSearchSection, allElkIdsSection, singleDocSection].forEach(section => {
            section.classList.add('hidden');
        });

        // 激活选中标签
        switch(tabName) {
            case 'local':
                localFilesTab.classList.add('tab-active');
                localFilesTab.classList.remove('text-gray-600', 'hover:bg-gray-100');
                localFilesSection.classList.remove('hidden');
                break;
            case 'elk-search':
                elkSearchTab.classList.add('tab-active');
                elkSearchTab.classList.remove('text-gray-600', 'hover:bg-gray-100');
                elkSearchSection.classList.remove('hidden');
                break;
            case 'all-elk-ids':
                allElkIdsTab.classList.add('tab-active');
                allElkIdsTab.classList.remove('text-gray-600', 'hover:bg-gray-100');
                allElkIdsSection.classList.remove('hidden');
                break;
            case 'single-doc':
                singleDocTab.classList.add('tab-active');
                singleDocTab.classList.remove('text-gray-600', 'hover:bg-gray-100');
                singleDocSection.classList.remove('hidden');
                break;
        }
    }

    // 拖放事件处理
    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
        fileDropArea.addEventListener(eventName, preventDefaults, false);
    });

    function preventDefaults(e) {
        e.preventDefault();
        e.stopPropagation();
    }

    ['dragenter', 'dragover'].forEach(eventName => {
        fileDropArea.addEventListener(eventName, highlight, false);
    });

    ['dragleave', 'drop'].forEach(eventName => {
        fileDropArea.addEventListener(eventName, unhighlight, false);
    });

    function highlight() {
        fileDropArea.classList.add('file-drop-active');
    }

    function unhighlight() {
        fileDropArea.classList.remove('file-drop-active');
    }

    // 处理文件拖放
    fileDropArea.addEventListener('drop', handleDrop, false);

    function handleDrop(e) {
        const dt = e.dataTransfer;
        const files = dt.files;
        handleFiles(files);
    }

    // 处理文件选择
    fileInput.addEventListener('change', function() {
        handleFiles(this.files);
    });

    // 点击上传区域触发文件选择
    fileDropArea.addEventListener('click', () => {
        fileInput.click();
    });

    // 存储待上传的文件
    let filesToUpload = [];

    // 处理选择的文件
    function handleFiles(files) {
        if (files.length > 0) {
            filesToUpload = Array.from(files);
            showStatusMessage(`已选择 ${filesToUpload.length} 个文件`, 'info');
        }
    }

    // 上传按钮点击事件
    uploadBtn.addEventListener('click', () => {
        if (filesToUpload.length === 0) {
            showStatusMessage('请先选择文件', 'error');
            return;
        }
        uploadFilesSequentially(filesToUpload);
    });

    // 依次上传文件
    function uploadFilesSequentially(files, index = 0) {
        if (index >= files.length) {
            showStatusMessage('所有文件上传完成', 'success');
            filesToUpload = [];
            loadLocalFileList(); // 上传完成后重新加载列表
            return;
        }

        const file = files[index];
        uploadFile(file, () => {
            uploadFilesSequentially(files, index + 1);
        });
    }

    // 上传单个文件
    function uploadFile(file, onComplete) {
        const formData = new FormData();
        formData.append('file', file);

        const xhr = new XMLHttpRequest();
        xhr.open('POST', `${API_BASE_URL}/document/upload`, true);

        // 显示进度
        xhr.upload.addEventListener('progress', function(e) {
            if (e.lengthComputable) {
                const percent = Math.round((e.loaded / e.total) * 100);
                progressBar.style.width = percent + '%';
                progressPercent.textContent = percent + '%';
                progressFileName.textContent = file.name;
                progressContainer.classList.remove('hidden');
            }
        });

        // 上传完成
        xhr.addEventListener('load', function() {
            progressContainer.classList.add('hidden'); // 隐藏进度条
            if (xhr.status === 200) {
                showStatusMessage(`文件 "${file.name}" 上传成功`, 'success');
            } else {
                showStatusMessage(`文件 "${file.name}" 上传失败 (状态码: ${xhr.status})`, 'error');
            }
            onComplete();
        });

        // 上传错误
        xhr.addEventListener('error', function() {
            progressContainer.classList.add('hidden');
            showStatusMessage(`文件 "${file.name}" 上传出错`, 'error');
            onComplete();
        });

        xhr.send(formData);
    }

    // 显示状态消息
    function showStatusMessage(message, type) {
        statusMessage.textContent = message;
        statusMessage.classList.remove('hidden', 'bg-green-100', 'text-green-800', 'bg-red-100', 'text-red-800', 'bg-blue-100', 'text-blue-800');

        switch(type) {
            case 'success':
                statusMessage.classList.add('bg-green-100', 'text-green-800');
                break;
            case 'error':
                statusMessage.classList.add('bg-red-100', 'text-red-800');
                break;
            default:
                statusMessage.classList.add('bg-blue-100', 'text-blue-800');
        }

        // 5秒后自动隐藏
        setTimeout(() => {
            statusMessage.classList.add('hidden');
        }, 5000);
    }

    // 格式化文件大小
    function formatFileSize(bytes) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    // 格式化日期时间（适配LocalDateTime格式）
    function formatDateTime(dateTimeStr) {
        if (!dateTimeStr) return '未知时间';
        const date = new Date(dateTimeStr);
        return date.toLocaleString();
    }

    // 获取文件图标
    function getFileIcon(fileType) {
        if (fileType.includes('pdf')) return 'fa-file-pdf-o text-red-500';
        if (fileType.includes('word') || fileType.includes('doc')) return 'fa-file-word-o text-blue-500';
        if (fileType.includes('json')) return 'fa-file-code-o text-purple-500';
        if (fileType.includes('text')) return 'fa-file-text-o text-gray-500';
        return 'fa-file-o text-gray-400';
    }

    // 获取文件类型显示文本
    function getFileTypeText(fileType) {
        if (fileType.includes('pdf')) return 'PDF文档';
        if (fileType.includes('word') || fileType.includes('doc')) return 'Word文档';
        if (fileType.includes('json')) return 'JSON文件';
        if (fileType.includes('text')) return '文本文件';
        return fileType || '未知类型';
    }

    // ==================== 本地文件管理 ====================

    // 渲染本地文件列表
    function renderLocalFileList(files) {
        if (files.length === 0) {
            localFileList.innerHTML = `
                <div class="text-center py-12 text-gray-500">
                    <i class="fa fa-folder-open-o text-4xl mb-3"></i>
                    <p>暂无上传的文件</p>
                </div>
            `;
            updateLocalBatchDeleteButton();
            return;
        }

        localFileList.innerHTML = files.map(file => `
            <div class="py-4 flex flex-wrap items-center justify-between card-hover">
                <div class="flex items-center">
                    <input type="checkbox" class="local-file-select-checkbox mr-3 h-4 w-4 text-primary rounded" data-id="${file.id}">
                    <i class="fa ${getFileIcon(file.fileType)} text-xl mr-3"></i>
                    <div>
                        <p class="font-medium text-gray-800">${file.fileName}</p>
                        <p class="text-sm text-gray-500">
                            ID: ${file.id} ·
                            ${formatFileSize(file.fileSize)} ·
                            ${formatDateTime(file.uploadTime)} ·
                            ${getFileTypeText(file.fileType)}
                        </p>
                    </div>
                </div>
                <div class="mt-2 sm:mt-0">
                    <button class="delete-local-btn text-danger hover:text-danger/80 transition-colors ml-2" data-id="${file.id}">
                        <i class="fa fa-trash-o mr-1"></i>删除
                    </button>
                </div>
            </div>
        `).join('');

        // 为删除按钮添加事件监听
        document.querySelectorAll('.delete-local-btn').forEach(btn => {
            btn.addEventListener('click', function() {
                const fileId = this.getAttribute('data-id');
                deleteFile([fileId]);
            });
        });

        // 为复选框添加事件监听
        document.querySelectorAll('.local-file-select-checkbox').forEach(checkbox => {
            checkbox.addEventListener('change', updateLocalBatchDeleteButton);
        });

        updateLocalBatchDeleteButton();
    }

    // 更新本地文件批量删除按钮状态
    function updateLocalBatchDeleteButton() {
        const checkedBoxes = document.querySelectorAll('.local-file-select-checkbox:checked');
        if (checkedBoxes.length > 0) {
            batchDeleteBtn.classList.remove('hidden');
            batchDeleteBtn.innerHTML = `<i class="fa fa-trash-o mr-1"></i>批量删除 (${checkedBoxes.length})`;
        } else {
            batchDeleteBtn.classList.add('hidden');
        }
    }

    // 本地文件全选/取消全选
    selectAllBtn.addEventListener('click', () => {
        document.querySelectorAll('.local-file-select-checkbox').forEach(checkbox => checkbox.checked = true);
        updateLocalBatchDeleteButton();
    });

    deselectAllBtn.addEventListener('click', () => {
        document.querySelectorAll('.local-file-select-checkbox').forEach(checkbox => checkbox.checked = false);
        updateLocalBatchDeleteButton();
    });

    // 本地文件批量删除
    batchDeleteBtn.addEventListener('click', () => {
        const checkedBoxes = document.querySelectorAll('.local-file-select-checkbox:checked');
        const idsToDelete = Array.from(checkedBoxes).map(cb => cb.getAttribute('data-id'));

        if (idsToDelete.length > 0 && confirm(`确定要删除这 ${idsToDelete.length} 个文件吗？`)) {
            deleteFile(idsToDelete);
        }
    });

    // 加载本地文件列表
    function loadLocalFileList(searchTerm = '') {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', `${API_BASE_URL}/document/list`, true);

        xhr.addEventListener('load', function() {
            if (xhr.status === 200) {
                try {
                    const fileInfos = JSON.parse(xhr.responseText);
                    const filteredFiles = searchTerm
                        ? fileInfos.filter(file =>
                            file.fileName.toLowerCase().includes(searchTerm) ||
                            file.id.toLowerCase().includes(searchTerm) ||
                            getFileTypeText(file.fileType).toLowerCase().includes(searchTerm)
                        )
                        : fileInfos;
                    renderLocalFileList(filteredFiles);
                } catch (error) {
                    showStatusMessage(`解析文件列表失败: ${error.message}`, 'error');
                }
            } else {
                showStatusMessage(`获取文件列表失败 (状态码: ${xhr.status})`, 'error');
            }
        });

        xhr.addEventListener('error', () => showStatusMessage('获取文件列表时发生网络错误', 'error'));
        xhr.send();
    }

    // 本地文件搜索
    searchLocalFiles.addEventListener('input', function() {
        loadLocalFileList(this.value.toLowerCase());
    });

    // ==================== ELK搜索功能 ====================

    // 渲染ELK查询结果
    function renderElkFileList(documents) {
        if (documents.length === 0) {
            elkFileList.innerHTML = `
                <div class="text-center py-12 text-gray-500">
                    <i class="fa fa-search text-4xl mb-3"></i>
                    <p>未找到匹配的文档</p>
                </div>
            `;
            updateElkBatchDeleteButton();
            return;
        }

        elkFileList.innerHTML = documents.map(doc => `
            <div class="py-4 flex flex-wrap items-start justify-between card-hover">
                <div class="flex-1 min-w-0">
                    <div class="flex items-center mb-2">
                        <input type="checkbox" class="elk-file-select-checkbox mr-3 h-4 w-4 text-primary rounded mt-1" data-id="${doc.id}">
                        <i class="fa fa-file-text-o text-xl mr-3 text-primary"></i>
                        <div class="font-medium text-gray-800 truncate">文档 ID: ${doc.id}</div>
                    </div>
                    <div class="ml-8 mt-1">
                        <p class="text-sm text-gray-700 mb-2 line-clamp-3">${doc.text || '无内容'}</p>
                        ${doc.metadata ? `
                        <div class="text-xs text-gray-500 mt-1">
                            <span>相似度: ${(doc.metadata.score || 0).toFixed(4)}</span>
                            ${doc.metadata.index ? `<span class="ml-2">索引: ${doc.metadata.index}</span>` : ''}
                        </div>
                        ` : ''}
                    </div>
                </div>
                <div class="mt-2 sm:mt-0">
                    <button class="delete-elk-btn text-danger hover:text-danger/80 transition-colors ml-2" data-id="${doc.id}">
                        <i class="fa fa-trash-o mr-1"></i>删除
                    </button>
                </div>
            </div>
        `).join('');

        // 为删除按钮添加事件监听
        document.querySelectorAll('.delete-elk-btn').forEach(btn => {
            btn.addEventListener('click', function() {
                deleteFile([this.getAttribute('data-id')]);
            });
        });

        // 为复选框添加事件监听
        document.querySelectorAll('.elk-file-select-checkbox').forEach(checkbox => {
            checkbox.addEventListener('change', updateElkBatchDeleteButton);
        });

        updateElkBatchDeleteButton();
    }

    // 更新ELK批量删除按钮状态
    function updateElkBatchDeleteButton() {
        const checkedBoxes = document.querySelectorAll('.elk-file-select-checkbox:checked');
        if (checkedBoxes.length > 0) {
            batchDeleteElkBtn.classList.remove('hidden');
            batchDeleteElkBtn.innerHTML = `<i class="fa fa-trash-o mr-1"></i>批量删除 (${checkedBoxes.length})`;
        } else {
            batchDeleteElkBtn.classList.add('hidden');
        }
    }

    // ELK文档全选/取消全选
    selectAllElkBtn.addEventListener('click', () => {
        document.querySelectorAll('.elk-file-select-checkbox').forEach(checkbox => checkbox.checked = true);
        updateElkBatchDeleteButton();
    });

    deselectAllElkBtn.addEventListener('click', () => {
        document.querySelectorAll('.elk-file-select-checkbox').forEach(checkbox => checkbox.checked = false);
        updateElkBatchDeleteButton();
    });

    // ELK文档批量删除
    batchDeleteElkBtn.addEventListener('click', () => {
        const checkedBoxes = document.querySelectorAll('.elk-file-select-checkbox:checked');
        const idsToDelete = Array.from(checkedBoxes).map(cb => cb.getAttribute('data-id'));

        if (idsToDelete.length > 0 && confirm(`确定要删除这 ${idsToDelete.length} 个ELK文档吗？`)) {
            deleteFile(idsToDelete);
        }
    });

    // 删除所有ELK文档
    deleteAllElkBtn.addEventListener('click', () => {
        if (confirm('确定要删除Elasticsearch中的所有文档吗？此操作不可恢复！')) {
            const xhr = new XMLHttpRequest();
            xhr.open('DELETE', `${API_BASE_URL}/document/delAll`, true);

            xhr.addEventListener('load', function() {
                if (xhr.status === 204) {
                    showStatusMessage('所有ELK文档已成功删除', 'success');
                    renderElkFileList([]);
                } else {
                    showStatusMessage(`删除失败 (状态码: ${xhr.status})`, 'error');
                }
            });

            xhr.addEventListener('error', () => showStatusMessage('删除时发生错误', 'error'));
            xhr.send();
        }
    });

    // 执行ELK查询
    searchElkBtn.addEventListener('click', () => {
        const query = elkQueryText.value.trim();
        const topK = parseInt(elkTopK.value) || 5;

        if (!query) {
            showStatusMessage('请输入查询文本', 'error');
            return;
        }

        if (topK < 1 || topK > 100) {
            showStatusMessage('返回数量必须在1-100之间', 'error');
            return;
        }

        searchElkDocuments(query, topK);
    });

    // 按Enter键执行查询
    elkQueryText.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') searchElkBtn.click();
    });

    // 调用ELK搜索接口
    function searchElkDocuments(query, topK) {
        const xhr = new XMLHttpRequest();
        const params = new URLSearchParams({ query, topK });
        xhr.open('GET', `${API_BASE_URL}/document/search/text?${params}`, true);

        xhr.addEventListener('load', function() {
            if (xhr.status === 200) {
                try {
                    const documents = JSON.parse(xhr.responseText);
                    renderElkFileList(documents);
                    showStatusMessage(`找到 ${documents.length} 个匹配文档`, 'success');
                } catch (error) {
                    showStatusMessage(`解析结果失败: ${error.message}`, 'error');
                }
            } else {
                showStatusMessage(`查询失败 (状态码: ${xhr.status})`, 'error');
            }
        });

        xhr.addEventListener('error', () => showStatusMessage('查询时发生网络错误', 'error'));
        xhr.send();
    }

    // ==================== 所有ELK文档ID功能 ====================

    // 获取所有ELK文档ID
    fetchAllElkIdsBtn.addEventListener('click', () => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', `${API_BASE_URL}/document/all-ids`, true);

        // 显示加载状态
        allElkIdsList.innerHTML = `
            <div class="text-center py-12 text-gray-500">
                <i class="fa fa-spinner fa-spin text-4xl mb-3"></i>
                <p>正在获取所有文档ID...</p>
            </div>
        `;

        xhr.addEventListener('load', function() {
            if (xhr.status === 200) {
                try {
                    const ids = JSON.parse(xhr.responseText);
                    renderAllElkIds(ids);
                    showStatusMessage(`共获取到 ${ids.length} 个文档ID`, 'success');
                } catch (error) {
                    showStatusMessage(`解析ID列表失败: ${error.message}`, 'error');
                    allElkIdsList.innerHTML = `
                        <div class="text-center py-12 text-red-500">
                            <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                            <p>解析ID列表失败</p>
                        </div>
                    `;
                }
            } else {
                showStatusMessage(`获取失败 (状态码: ${xhr.status})`, 'error');
                allElkIdsList.innerHTML = `
                    <div class="text-center py-12 text-red-500">
                        <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                        <p>获取ID列表失败</p>
                    </div>
                `;
            }
        });

        xhr.addEventListener('error', () => {
            showStatusMessage('获取时发生网络错误', 'error');
            allElkIdsList.innerHTML = `
                <div class="text-center py-12 text-red-500">
                    <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                    <p>网络错误</p>
                </div>
            `;
        });

        xhr.send();
    });

    // 渲染所有ELK文档ID
    function renderAllElkIds(ids) {
        if (ids.length === 0) {
            allElkIdsList.innerHTML = `
                <div class="text-center py-12 text-gray-500">
                    <i class="fa fa-list-ol text-4xl mb-3"></i>
                    <p>Elasticsearch中没有文档</p>
                </div>
            `;
            return;
        }

        // 生成带复制功能的ID列表
        allElkIdsList.innerHTML = `
            <div class="mb-4 flex justify-between items-center">
                <p class="text-sm text-gray-600">共 ${ids.length} 个文档ID</p>
                <button id="copyAllIdsBtn" class="text-primary hover:text-primary/80 text-sm">
                    <i class="fa fa-copy mr-1"></i>复制所有ID
                </button>
            </div>
            <ul class="space-y-2">
                ${ids.map(id => `
                    <li class="flex items-center justify-between p-2 bg-white rounded border border-gray-200">
                        <span class="text-sm truncate">${id}</span>
                        <button class="copy-id-btn text-gray-400 hover:text-primary" data-id="${id}">
                            <i class="fa fa-copy"></i>
                        </button>
                    </li>
                `).join('')}
            </ul>
        `;

        // 单个ID复制功能
        document.querySelectorAll('.copy-id-btn').forEach(btn => {
            btn.addEventListener('click', function() {
                const id = this.getAttribute('data-id');
                navigator.clipboard.writeText(id).then(() => {
                    const originalIcon = this.innerHTML;
                    this.innerHTML = '<i class="fa fa-check text-green-500"></i>';
                    setTimeout(() => this.innerHTML = originalIcon, 2000);
                });
            });
        });

        // 复制所有ID功能
        document.getElementById('copyAllIdsBtn').addEventListener('click', function() {
            const text = ids.join('\n');
            navigator.clipboard.writeText(text).then(() => {
                const originalText = this.innerHTML;
                this.innerHTML = '<i class="fa fa-check mr-1"></i>已复制';
                setTimeout(() => this.innerHTML = originalText, 2000);
            });
        });
    }

    // 从ID列表页面删除所有文档
    deleteAllFromIdsBtn.addEventListener('click', () => {
        if (confirm('确定要删除Elasticsearch中的所有文档吗？此操作不可恢复！')) {
            const xhr = new XMLHttpRequest();
            xhr.open('DELETE', `${API_BASE_URL}/document/delAll`, true);

            xhr.addEventListener('load', function() {
                if (xhr.status === 204) {
                    showStatusMessage('所有ELK文档已成功删除', 'success');
                    allElkIdsList.innerHTML = `
                        <div class="text-center py-12 text-green-500">
                            <i class="fa fa-check-circle text-4xl mb-3"></i>
                            <p>所有文档已成功删除</p>
                        </div>
                    `;
                } else {
                    showStatusMessage(`删除失败 (状态码: ${xhr.status})`, 'error');
                }
            });

            xhr.addEventListener('error', () => showStatusMessage('删除时发生错误', 'error'));
            xhr.send();
        }
    });

    // ==================== 单个文档查询功能 ====================

    // 查询单个文档
    fetchSingleDocBtn.addEventListener('click', () => {
        const docId = singleDocId.value.trim();
        if (!docId) {
            showStatusMessage('请输入文档ID', 'error');
            return;
        }

        // 显示加载状态
        singleDocContent.innerHTML = `
            <div class="p-6 text-center text-gray-500">
                <i class="fa fa-spinner fa-spin text-4xl mb-3"></i>
                <p>正在查询文档ID: ${docId}</p>
            </div>
        `;

        const xhr = new XMLHttpRequest();
        xhr.open('GET', `${API_BASE_URL}/document/${docId}`, true);

        xhr.addEventListener('load', function() {
            if (xhr.status === 200) {
                try {
                    const doc = JSON.parse(xhr.responseText);
                    renderSingleDocument(doc);
                    showStatusMessage('文档查询成功', 'success');
                } catch (error) {
                    showStatusMessage(`解析文档失败: ${error.message}`, 'error');
                    singleDocContent.innerHTML = `
                        <div class="p-6 text-center text-red-500">
                            <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                            <p>解析文档内容失败</p>
                        </div>
                    `;
                }
            } else if (xhr.status === 404) {
                singleDocContent.innerHTML = `
                    <div class="p-6 text-center text-gray-500">
                        <i class="fa fa-search text-4xl mb-3"></i>
                        <p>未找到ID为 ${docId} 的文档</p>
                    </div>
                `;
            } else {
                showStatusMessage(`查询失败 (状态码: ${xhr.status})`, 'error');
                singleDocContent.innerHTML = `
                    <div class="p-6 text-center text-red-500">
                        <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                        <p>查询失败</p>
                    </div>
                `;
            }
        });

        xhr.addEventListener('error', () => {
            showStatusMessage('查询时发生网络错误', 'error');
            singleDocContent.innerHTML = `
                <div class="p-6 text-center text-red-500">
                    <i class="fa fa-exclamation-circle text-4xl mb-3"></i>
                    <p>网络错误</p>
                </div>
            `;
        });

        xhr.send();
    });

    // 按Enter键查询单个文档
    singleDocId.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') fetchSingleDocBtn.click();
    });

    // 渲染单个文档内容
    function renderSingleDocument(doc) {
        singleDocContent.innerHTML = `
            <div class="border-b border-gray-200 px-6 py-4 bg-gray-50">
                <div class="flex justify-between items-center">
                    <h3 class="font-semibold text-gray-800">文档 ID: ${doc.id}</h3>
                    <button class="delete-single-doc-btn bg-danger hover:bg-danger/90 text-white text-sm py-1 px-3 rounded-md transition-colors">
                        <i class="fa fa-trash-o mr-1"></i>删除
                    </button>
                </div>
                ${doc.metadata ? `
                <div class="mt-2 text-xs text-gray-500">
                    ${Object.entries(doc.metadata).map(([key, value]) => `
                        <span class="mr-3">${key}: ${value}</span>
                    `).join('')}
                </div>
                ` : ''}
            </div>
            <div class="p-6">
                <h4 class="font-medium text-gray-700 mb-3">文档内容:</h4>
                <div class="whitespace-pre-line text-gray-800 leading-relaxed">${doc.text || '无内容'}</div>
            </div>
        `;

        // 添加删除事件监听
        document.querySelector('.delete-single-doc-btn').addEventListener('click', function() {
            if (confirm(`确定要删除ID为 ${doc.id} 的文档吗？`)) {
                deleteFile([doc.id]);
                singleDocId.value = ''; // 清空输入框
            }
        });
    }

    // 通用删除文件方法
    function deleteFile(documentIds) {
        const xhr = new XMLHttpRequest();
        const params = new URLSearchParams({ documentIds: documentIds.join(',') });
        xhr.open('DELETE', `${API_BASE_URL}/document/delete?${params}`, true);

        xhr.addEventListener('load', function() {
            if (xhr.status === 200) {
                showStatusMessage(`成功删除 ${documentIds.length} 个文件`, 'success');
                // 刷新相关列表
                loadLocalFileList();
                // 如果在ELK搜索标签页且有查询内容，重新查询
                if (!elkSearchSection.classList.contains('hidden') && elkQueryText.value.trim()) {
                    searchElkDocuments(elkQueryText.value.trim(), parseInt(elkTopK.value) || 5);
                }
                // 如果在所有ID标签页，重新加载ID列表
                if (!allElkIdsSection.classList.contains('hidden')) {
                    fetchAllElkIdsBtn.click();
                }
                // 如果在单个文档标签页，清空内容
                if (!singleDocSection.classList.contains('hidden')) {
                    singleDocContent.innerHTML = `
                        <div class="p-6 text-center text-green-500">
                            <i class="fa fa-check-circle text-4xl mb-3"></i>
                            <p>文档已成功删除</p>
                        </div>
                    `;
                }
            } else {
                showStatusMessage(`删除失败 (状态码: ${xhr.status})`, 'error');
            }
        });

        xhr.addEventListener('error', () => showStatusMessage('删除时发生网络错误', 'error'));
        xhr.send();
    }

    // 初始化页面
    document.addEventListener('DOMContentLoaded', () => {
        initTabs();
        loadLocalFileList();
        switchTab('local'); // 默认显示本地文件标签
    });
</script>
</body>
</html>